﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace EasyTrader.Signal
{
    public class HighLowSignalManager : EasyTrader.Signal.SignalManager
    {
        EasyTrader.Signal.ForecastingInfo m_Fore = new EasyTrader.Signal.ForecastingInfo();
        private double m_DayHeight = 0;
        public double DayHeight
        {
            get { return m_DayHeight; }
            set { m_DayHeight = value; }
        }
        private double m_DayHigh = 0;
        public double DayHigh
        {
            get { return m_DayHigh; }
            set { m_DayHigh = value; }
        }
        private double m_DayLow = 0;
        public double DayLow
        {
            get { return m_DayLow; }
            set { m_DayLow = value; }
        }
        private double m_DayCloseMax = 0.0;
        public double DayCloseMax
        {
            get { return m_DayCloseMax; }
            set { m_DayCloseMax = value; }
        }
        private double m_DayCloseMin = 0.0;
        public double DayCloseMin
        {
            get { return m_DayCloseMin; }
            set { m_DayCloseMin = value; }
        }
        private double m_HighLimit = 0; // 이 값 밑으로 내려와야 신호 발생
        public double HighLimit
        {
            get { return m_HighLimit; }
            set { m_HighLimit = value; }
        }
        private double m_LowLimit = 0; // 이 값 위로 올라와야 신호 발생
        public double LowLimit
        {
            get { return m_LowLimit; }
            set { m_LowLimit = value; }
        }
        private double m_CurVal = 0;
        public double CurVal
        {
            get { return m_CurVal; }
            set { m_CurVal = value; }
        }
        public HighLowSignalManager()
            : base()
        {
            
        }

        public double GetHighLowSignal(int a_CurIndex)
        {
            double signalVal = GlobalVar.SignalNone;

            GetForecastingInfo(m_Fore, "종가", GlobalVar.RegressionType, a_CurIndex, GlobalVar.ReferenceRange);
            if (m_Fore.StartX == -1 || m_Fore.EndX == -1)
                return signalVal;

            if (GlobalVar.DayHeight < GlobalVar.SignalWaveHeight || GlobalVar.CurClose == 0.0 || GlobalVar.DayHeight == 0)
                return signalVal;

            double deltaY = m_Fore.EndY - m_Fore.StartY;
            if (deltaY > 0)
            {
                double deltaHigh = Math.Abs(GlobalVar.CurClose - GlobalVar.DayLow);
                signalVal = (deltaHigh / GlobalVar.DayHeight) * 100.0;
            }
            else
            {
                double deltaLow = Math.Abs(GlobalVar.DayHigh - GlobalVar.CurClose);
                signalVal = -(deltaLow / GlobalVar.DayHeight) * 100.0;
            }
            return signalVal;
        }

        public int GetForecastingInfo(ForecastingInfo a_Fore, string a_ColName, string a_RegType, int a_EndX, int a_MaxRange)
        {
            if (a_ColName == "" || a_EndX < 0 || a_MaxRange < 0 || a_Fore == null)
                return -1;
            EasyTrader.DataSet.ETDataTable curTable = (EasyTrader.DataSet.ETDataTable)m_EasyTraderDataSet.GetFutOptChartTable();
            if (curTable == null)
                return -1;
            int rowCount = curTable.GetRowCount();
            if (rowCount == 0)
                return -1;
            int startX = GetStartX(a_EndX, a_MaxRange);
            startX = Math.Min(startX, curTable.GetRowCount() - 1);
            DataRow row = curTable.Rows[startX];
            double openVal = Convert.ToDouble(row["시가"]);
            return Forecaster.GetForecastingInfoWithOpen(a_Fore, curTable, a_ColName, a_RegType, a_EndX, a_MaxRange, openVal);
        }

        public override int GetSignal(int a_CurIndex)
        {
            int signalVal = GlobalVar.SignalNone;

            int result = GetForecastingInfo("종가", GlobalVar.RegressionType, a_CurIndex, GlobalVar.ReferenceRange, false);

            if (result < 0 || m_Fore == null)
                return signalVal;

            double deltaY = m_Fore.EndY - m_Fore.StartY;

            if (deltaY > 0 && CurVal > m_LowLimit)
            {
                signalVal = GlobalVar.SignalBuy;
            }

            if (deltaY < 0 && CurVal < m_HighLimit)
            {
                signalVal = GlobalVar.SignalSell;
            }

            return signalVal;
        }

        public void SetDayHighLowInfo()
        {
            EasyTrader.DataSet.ETDataTable curTable = (EasyTrader.DataSet.ETDataTable)m_EasyTraderDataSet.GetFutOptChartTable();

            if (curTable == null)
                return;
            int rowCount = curTable.Rows.Count;
            if (rowCount == 0)
                return;
            double high = 0;
            double low = 0;
            double close = 0.0;
            m_DayHigh = -10000.0;
            m_DayLow = 1000.0;
            m_DayCloseMax = -10000.0;
            m_DayCloseMin = 10000.0;
            DataRow row = null;
            for (int i = 0; i < rowCount; i++)
            {
                row = curTable.Rows[i];
                high = Convert.ToDouble(row["고가"]);
                low = Convert.ToDouble(row["저가"]);
                close = Convert.ToDouble(row["종가"]);
                if (high > m_DayHigh)
                    m_DayHigh = high;
                if (low < m_DayLow)
                    m_DayLow = low;
                if (close < m_DayCloseMin)
                    m_DayCloseMin = close;
                if (close > m_DayCloseMax)
                    m_DayCloseMax = close;
            }
            
            GlobalVar.DayHigh = m_DayHigh;
            GlobalVar.DayLow = m_DayLow;
            m_DayHeight = Math.Abs(m_DayHigh - m_DayLow);
            m_HighLimit = m_DayHigh - m_DayHeight * GlobalVar.HighLowPercent;
            m_LowLimit = m_DayLow + m_DayHeight * GlobalVar.HighLowPercent;
            CurVal = Convert.ToDouble(row["종가"]);
            GlobalVar.DayHeight = m_DayHeight;
        }


        public void SetDayHighLowInfo(int a_CurIndex)
        {
            EasyTrader.DataSet.ETDataTable curTable = (EasyTrader.DataSet.ETDataTable)m_EasyTraderDataSet.GetFutOptChartTable();

            if (curTable == null)
                return;
            int rowCount = curTable.Rows.Count;
            if (rowCount == 0)
                return;
            if (a_CurIndex > rowCount - 1)
                a_CurIndex = rowCount - 1;
            double high = 0;
            double low = 0;
            double close = 0.0;
            m_DayHigh = -10000.0;
            m_DayLow = 10000.0;
            m_DayCloseMax = -10000.0;
            m_DayCloseMin = 10000.0;
            DataRow row = null;
            for (int i = 0; i <= a_CurIndex; i++)
            {
                row = curTable.Rows[i];
                high = Convert.ToDouble(row["고가"]);
                low = Convert.ToDouble(row["저가"]);
                close = Convert.ToDouble(row["종가"]);
                if (high > m_DayHigh)
                    m_DayHigh = high;
                if (low < m_DayLow)
                    m_DayLow = low;
                if (close < m_DayCloseMin)
                    m_DayCloseMin = close;
                if (close > m_DayCloseMax)
                    m_DayCloseMax = close;
            }

            GlobalVar.DayHigh = m_DayHigh;
            GlobalVar.DayLow = m_DayLow;
            DayHeight = Math.Abs(m_DayHigh - m_DayLow);
            m_HighLimit = m_DayHigh - DayHeight * GlobalVar.HighLowPercent;
            m_LowLimit = m_DayLow + DayHeight * GlobalVar.HighLowPercent;
            CurVal = Convert.ToDouble(row["종가"]);
            GlobalVar.DayHeight = DayHeight;
        }

        public int GetForecastingInfo(string a_ColName, string a_RegType, int a_CurIndex, int a_MaxRange, bool a_AllowZero)
        {
            EasyTrader.DataSet.ETDataTable curTable = (EasyTrader.DataSet.ETDataTable)m_EasyTraderDataSet.GetFutOptChartTable();
            if (m_Forecaster == null || m_Fore == null || curTable == null)
            {
                return -1;
            }
            return Forecaster.GetForecastingInfo(m_Fore, curTable, a_ColName, a_RegType, a_CurIndex, a_MaxRange, a_AllowZero);
        }
    }
}
